import os
from dotenv import load_dotenv

load_dotenv()  # 自动加载.env文件

from fastapi import APIRouter, HTTPException, Request, Header
from pydantic import BaseModel
from database import add_journal_entry, get_all_journals, delete_journal_entry
from models.loader import CloudModel
import logging
from starlette.responses import JSONResponse 
import asyncio
from concurrent.futures import ThreadPoolExecutor, TimeoutError
from datetime import datetime, timedelta
import re
import hashlib
import jwt
from routes.user import get_current_user

# 日志配置
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# 初始化路由和模型
journal_router = APIRouter()
llm = CloudModel()
executor = ThreadPoolExecutor(max_workers=2)  # 控制线程数

JWT_SECRET = os.environ.get("JWT_SECRET", "default_secret")  # 优先用环境变量
JWT_ALGORITHM = "HS256"
JWT_EXPIRE_MINUTES = 7 * 24 * 60  # 7天

def run_llm_generate(prompt: str, max_tokens: int = 128):
    return llm.generate(prompt, max_tokens=max_tokens)

# 宝宝出生日期是 2025年3月27日
birth_date = datetime(2025, 3, 27)
current_date = datetime.now()
age_in_months = (current_date.year - birth_date.year) * 12 + current_date.month - birth_date.month

# 生成年龄描述
if age_in_months < 12:
    age_str = f"{age_in_months}个月"
else:
    years = age_in_months // 12
    months = age_in_months % 12
    age_str = f"{years}岁" + (f"{months}个月" if months else "")

def is_question(text):
    text = text.strip()
    # 结尾问号或"吗"
    if text.endswith('吗') or text.endswith('?') or text.endswith('？'):
        return True
    # 常见疑问词出现在句中
    question_keywords = [
        '什么', '多少', '怎么', '如何', '为何', '是不是', '能不能', '可不可以',
        '多重', '多大', '多高', '多长', '几岁', '几个月', '一般', '为啥', '为什'
    ]
    for word in question_keywords:
        if word in text:
            return True
    return False

class JournalEntry(BaseModel):
    content: str

class PromptRequest(BaseModel):
    text: str

@journal_router.post("/journals")
async def create_journal(entry: JournalEntry, token: str = Header(...)):
    username = get_current_user(token)
    user_input = entry.content.strip()
    if is_question(user_input):
        # 需要加背景设定
        if '橙橙' in user_input:
            prompt = f"""
            请记住：橙橙是用户的儿子，出生于{birth_date.strftime('%Y年%m月%d日')}，现在{age_str}大。
            用户提问：{user_input}
            请用简洁中文直接回答用户的问题。
            """
        else:
            prompt = f"""
            用户提问：{user_input}
            请用简洁中文直接回答用户的问题。
            """
        answer = llm.generate(prompt)
        add_journal_entry(user_input, answer, username, type='qa')
        return JSONResponse(content={"status": "qa", "answer": answer})
    else:
        # 走日记摘要流程（原有逻辑）
        try:
            user_input = entry.content.encode('utf-8', errors='ignore').decode('utf-8')
        except Exception:
            user_input = entry.content

        MAX_INPUT_LENGTH = 512
        user_input = user_input[:MAX_INPUT_LENGTH]

        # 构建更详细的提示词
        if '橙橙' in user_input:
            prompt = f"""
            【系统提示】今天是 {current_date.strftime('%Y年%m月%d日')}，橙橙现在 {age_str}。
            你是一个善于理解情绪和心理状态的中文助手。
            请记住：橙橙（也叫胖仔）是用户的儿子，现在{age_str}大。关于橙橙的日记，请用温暖、积极的语言来描写他的表现。
            橙橙会经常出现在日记里。
            **如果日记内容没有提到橙橙，请不要自动生成与橙橙相关的内容。**
            请根据用户的日记内容，用**中文**生成一段日记描述。

            【输入】
            {user_input}

            【输出要求】
            - 语言自然、口语化，富有画面感
            - 不超过200字
            - 如果涉及情绪波动或辛苦，请以温和的方式表达，避免使用"疲惫"、"累"、"困倦"等词汇
            - **如果日记内容没有提到"橙橙"、"儿子"、"小家伙"等，请绝对不要生成与孩子相关的内容，也不要自动补充家庭成员。**
            - 只输出中文内容，可以带表情符号

            【输出】
            """
        else:
            prompt = f"""
            【系统提示】今天是 {current_date.strftime('%Y年%m月%d日')}，橙橙现在 {age_str}。
            你是一个善于理解情绪和心理状态的中文助手。
            请根据用户的日记内容，用**中文**生成一段日记描述。

            【输入】
            {user_input}

            【输出要求】
            - 语言自然、口语化，富有画面感
            - 不超过200字
            - 如果涉及情绪波动或辛苦，请以温和的方式表达，避免使用"疲惫"、"累"、"困倦"等词汇
            - 只输出中文内容，可以带表情符号

            【输出】
            """
        logging.info(f"Prompt sent to LLM: {prompt}")

        try:
            loop = asyncio.get_event_loop()
            summary = await asyncio.wait_for(
                loop.run_in_executor(executor, run_llm_generate, prompt),
                timeout=30  # 30秒超时
            )
            
            # 清理输出，移除可能的重复内容
            summary = summary.strip()
            
        except TimeoutError:
            logging.error("LLM call timed out.")
            # 使用简单的规则生成一个基础回复
            user_input_lower = user_input.lower()

        except Exception as e:
            logging.error(f"LLM call failed: {e}")
            summary = "[AI摘要] 模型调用失败，请重试。"

        logging.info(f"LLM returned raw output: '{summary}'")

        add_journal_entry(user_input, summary, username, type='diary')
        return JSONResponse(content={"status": "success", "summary": summary})


@journal_router.get("/journals")
def list_journals(token: str = Header(...)):
    username = get_current_user(token)
    # 只返回当前用户的日记
    all_journals = get_all_journals()
    print('all_journals',all_journals)
    user_journals = [j for j in all_journals if j.get('username') == username]
    # 只保留 status 为 'success' 的日记内容
    diary_journals = [j for j in user_journals if j.get('type') in (None, '', 'diary')]
    return diary_journals


@journal_router.post("/generate")
async def generate(request: PromptRequest):
    try:
        user_input = request.text.encode('utf-8', errors='ignore').decode('utf-8')
    except Exception:
        user_input = request.text

    MAX_INPUT_LENGTH = 512
    user_input = user_input[:MAX_INPUT_LENGTH]

    try:
        loop = asyncio.get_event_loop()
        generated_text = await asyncio.wait_for(
            loop.run_in_executor(executor, run_llm_generate, user_input),
            timeout=180
        )
    except TimeoutError:
        logging.error("Generation timed out.")
        generated_text = "[AI摘要] 生成超时，请稍后再试。"
    except Exception as e:
        logging.error(f"Generation failed: {e}")
        generated_text = "[AI摘要] 内部错误。"

    return JSONResponse(content={"generated_text": generated_text})


@journal_router.get("/health")
def health_check():
    return JSONResponse(content={"status": "ok"})


@journal_router.delete("/journals/{journal_id}")
def delete_journal(journal_id: int, token: str = Header(...)):
    get_current_user(token)
    try:
        delete_journal_entry(journal_id)
        return {"status": "success"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@journal_router.get("/analysis/topics")
async def get_topics_analysis(token: str = Header(...)):
    username = get_current_user(token)  # 获取当前用户
    all_journals = get_all_journals()
    # 只返回当前用户的日记
    user_journals = [j for j in all_journals if j.get('username') == username]
    
    if not user_journals:
        return JSONResponse(content={"topics": "暂无日记内容"})

    # 构建 prompt
    prompt = f"""
    请分析以下日记内容，按主题进行分类整理。重点关注：
    1. 橙橙相关：成长、生活、有趣表现
    2. 家庭生活：日常、心情
    3. 其他重要主题
    
    日记内容：
    {[entry['content'] for entry in user_journals]}
    
    请用简洁的方式整理出主题分类和对应内容摘要。
    """

    loop = asyncio.get_event_loop()
    topics = await loop.run_in_executor(executor, run_llm_generate, prompt, 1024)
    return JSONResponse(content={"topics": topics})

@journal_router.get("/analysis/timeline")
async def analyze_timeline(token: str = Header(...)):
    """生成日记时间线（仅当前用户）"""
    username = get_current_user(token)
    all_journals = get_all_journals()
    # 只返回当前用户的日记
    user_journals = [j for j in all_journals if j.get('username') == username]
    if not user_journals:
        return JSONResponse(content={"timeline": "暂无日记内容"})
    
    journal_texts = [
        f"时间：{datetime.fromisoformat(entry['created_at']).strftime('%Y-%m-%d %H:%M:%S')}\n内容：{entry['content']}"
        for entry in user_journals
    ]
    
    prompt = f"""
    请帮我梳理这段时间的日记要点，特别关注：
    1. 橙橙的成长变化和重要时刻
    2. 家庭生活的重要事件
    3. 值得记录的生活变化

    日记内容：
    {journal_texts}

    请按时间顺序整理，用以下格式输出：
    【时间1】
    - 重要事件/变化1
    - 重要事件/变化2

    【时间2】
    - 重要事件/变化1
    - 重要事件/变化2
    ...
    """
    
    loop = asyncio.get_event_loop()
    timeline = await loop.run_in_executor(executor, run_llm_generate, prompt, 1024)
    return JSONResponse(content={"timeline": timeline})

@journal_router.get("/analysis/growth")
async def analyze_growth(token: str = Header(...)):
    """分析橙橙的成长记录"""
    # journals = get_all_journals()
    
    username = get_current_user(token)
    all_journals = get_all_journals()
    # 只返回当前用户的日记
    user_journals = [j for j in all_journals if j.get('username') == username]
    if not user_journals:
        return JSONResponse(content={"growth": "暂无日记内容"})
    
    journal_texts = [
        f"时间：{datetime.fromisoformat(entry['created_at']).strftime('%Y-%m-%d %H:%M:%S')}\n内容：{entry['content']}"
        for entry in user_journals
    ]
    
    prompt = f"""
    请从日记中提取关于橙橙成长的重要记录，包括：
    1. 身体发育（身高、体重等）
    2. 能力发展（翻身、爬行、走路、说话等）
    3. 有趣表现和性格特点
    4. 生活习惯的变化

    日记内容：
    {journal_texts}

    请按发展领域分类整理，用以下格式输出：
    【身体发育】
    - 时间：具体变化
    - 时间：具体变化

    【能力发展】
    - 时间：具体变化
    - 时间：具体变化

    【性格特点】
    - 时间：具体表现
    - 时间：具体表现

    【生活习惯】
    - 时间：具体变化
    - 时间：具体变化
    """
    
    loop = asyncio.get_event_loop()
    growth = await loop.run_in_executor(executor, run_llm_generate, prompt)
    return JSONResponse(content={"growth": growth})

@journal_router.get("/analysis/emotion")
async def analyze_emotion(token: str = Header(...)):
    """分析日记中的情感变化"""
    # journals = get_all_journals()
    username = get_current_user(token)
    all_journals = get_all_journals()
    # 只返回当前用户的日记
    user_journals = [j for j in all_journals if j.get('username') == username]
    if not user_journals:
        return JSONResponse(content={"emotion": "暂无日记内容"})
    
    journal_texts = [
        f"时间：{datetime.fromisoformat(entry['created_at']).strftime('%Y-%m-%d %H:%M:%S')}\n内容：{entry['content']}"
        for entry in user_journals
    ]
    
    prompt = f"""
    请分析日记中的情感变化：
    1. 主要情绪类型和分布
    2. 情绪波动规律
    3. 影响情绪的主要因素
    4. 积极/消极情绪的比例

    日记内容：
    {journal_texts}

    请用以下格式输出：
    【情绪概览】
    - 主要情绪类型：xxx
    - 积极/消极情绪比例：xx/xx

    【情绪规律】
    - 发现1
    - 发现2

    【主要影响因素】
    - 因素1：影响说明
    - 因素2：影响说明

    【建议】
    - 建议1
    - 建议2
    """
    
    loop = asyncio.get_event_loop()
    emotion = await loop.run_in_executor(executor, run_llm_generate, prompt, 1024)
    return JSONResponse(content={"emotion": emotion})